package com.kpmg.datalake.autopackage.controller;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.kpmg.datalake.autopackage.service.ExcelService;
import com.kpmg.datalake.autopackage.vo.ExcelVo;
import com.kpmg.datalake.autopackage.vo.SourceDataManagerDTO;
import com.kpmg.datalake.common.enums.ResultCodeEnum;
import com.kpmg.datalake.common.utils.ResponseUtils;
import com.kpmg.datalake.common.utils.Utils;
import com.kpmg.datalake.common.vo.ServerResponse;
import com.kpmg.datalake.db.model.Project;
import com.kpmg.datalake.db.model.SysUsr;
import com.kpmg.datalake.operatelog.annotation.OptLog;
import com.kpmg.datalake.operatelog.enums.LogTypeEnum;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

/**
 * excel页面展示控制器
 *
 * @author james huang
 */
@RestController
@Api("PkgExcelController Package自动化excel控制器")
public class PkgExcelController {

  @Autowired
  private ExcelService excelService;


  private static final Logger logger = LoggerFactory.getLogger(PkgExcelController.class);

  private static final String SUCCESS = "success";
  private static final String UPLOAD = "upload";
  private static final String DATEFORMAT = "yyyyMMddHHmmss";

  /**
   * 跳转到查询数据报表
   *
   * @return
   */
  @ApiOperation(value = "跳转到查询excel数据报表", notes = "跳转到查询数据报表")
  @GetMapping(value = "/searchExcelData")
  public ModelAndView searchPkgData(HttpSession session) {
    ModelAndView view = new ModelAndView();
    view.setViewName("searchExcel_data");

    return view;
  }

  /**
   * 下载excel文件
   * 
   * @param sourceDataManagerDto
   * @param request
   * @param response
   */
  @RequestMapping(value = "/sourceDataMgr/resultExcelDownload")
  @OptLog(logType = LogTypeEnum.OPERATION, module = "autoPackage", description = "下载源数据")
  public void resultExcelDownload(@RequestBody SourceDataManagerDTO sourceDataManagerDto,
      HttpServletRequest request, HttpServletResponse response) throws IOException {
    String filePath = sourceDataManagerDto.getFilePath();
    String dataNm = sourceDataManagerDto.getDataNm();
    String ffx = filePath.substring(filePath.lastIndexOf('.') + 1);
    ResponseUtils.setZipDownloadResponseHeader(dataNm + "." + ffx, request, response);
    try (FileInputStream inputStream = new FileInputStream(filePath);) {
      this.downloadFile(inputStream, response);

    } catch (Exception e) {
      logger.error("下载查询请求结果文件异常:" + e.getMessage(), e);
      try (OutputStream outputStream = response.getOutputStream()) {
        String outString = JSONObject.toJSONString(ServerResponse.createByErrorCodeMessage(
            ResultCodeEnum.CODE4041.getCode(), e.getLocalizedMessage()));
        outputStream.write(outString.getBytes());
      }

    }

  }

  /**
   * 下载文件公用方法
   * 
   * @param inputStream
   * @param response
   * @throws IOException
   */
  private void downloadFile(FileInputStream inputStream, HttpServletResponse response)
      throws IOException {
    IOUtils.copy(inputStream, response.getOutputStream());
    response.flushBuffer();
  }

  private String status = "status";
  private String userHome = "user.home";

  /**
   * 上传新增excel模板
   *
   * @param bookSetFile
   * @param request
   * @return
   */
  @PostMapping(value = "/uploadExcelBookSet")
  public JSONObject uploadExcelBookSet(@RequestParam("selectedTemplate") MultipartFile bookSetFile,
      HttpServletRequest request) {
    JSONObject result = new JSONObject();
    result.put(status, true);

    try {

      SysUsr user = (SysUsr) request.getSession().getAttribute("user");
      File serverFile = this.uploadFile(bookSetFile, user);

      request.getSession().setAttribute("bookLocation", serverFile.getAbsolutePath());
      logger.info("filePath:{}", serverFile.getAbsolutePath());
      result.put("filePath", serverFile.getAbsolutePath());

    } catch (Exception e) {
      logger.error("上传筛选账套异常:" + e.getMessage(), e);
      result.put(status, false);
      result.put("msg", "上传筛选账套异常:" + e.getMessage());
    }

    return result;
  }

  private File uploadFile(MultipartFile bookSetFile, SysUsr user) throws IOException {
    // 设置上传账套路径
    String basePath = UPLOAD + File.separator;

    String personalPath = basePath + user.getUsrId() + File.separator;
    String uploadDir = System.getProperty(userHome) + File.separator + personalPath;
    // 创建账套文件路径
    File dir = new File(uploadDir);
    if (!dir.exists()) {
      dir.mkdirs();
    }
    String originalName = bookSetFile.getOriginalFilename();
    Date ss = new Date();
    SimpleDateFormat format0 = new SimpleDateFormat(DATEFORMAT);
    // 这个就是把时间戳经过处理得到期望格式的时间
    String time = format0.format(ss.getTime());
    String fileName = time + "." + originalName.substring(originalName.lastIndexOf('.') + 1);
    File serverFile = new File(uploadDir + fileName);
    bookSetFile.transferTo(serverFile);
    return serverFile;
  }

  /**
   * 修改excel
   *
   * @param bookSetFile
   * @param request
   * @return
   */
  @PostMapping(value = "/uploadEditExcelBookSet")
  public JSONObject uploadEditExcelBookSet(
      @RequestParam("editSelectedTemplate") MultipartFile bookSetFile, HttpServletRequest request) {
    JSONObject result = new JSONObject();
    result.put(status, true);

    try {

      SysUsr user = (SysUsr) request.getSession().getAttribute("user");

      File serverFile = this.uploadFile(bookSetFile, user);
      logger.info("serverFile:{}", serverFile);
      request.getSession().setAttribute("bookLocation", serverFile.getAbsolutePath());
      logger.info("filePath:{}", serverFile.getAbsolutePath());
      result.put("filePath", serverFile.getAbsolutePath());

    } catch (Exception e) {
      logger.error("上传模板异常:" + e.getMessage(), e);
      result.put(status, false);
      result.put("msg", "上传模板异常:" + e.getMessage());
    }

    return result;
  }

  /**
   * 查询excel请求列表
   *
   * @return
   */

  @PostMapping(value = "/sourceDataMgr/showExcelRqsList")
  @OptLog(logType = LogTypeEnum.OPERATION, module = "autoPackage", description = "查询源数据")
  public ServerResponse<PageInfo> showExcelRqsList(
      @RequestBody SourceDataManagerDTO sourceDataManagerDto) {

    try {
      // 获取请求记录列表
      return excelService.getSourceDataList(sourceDataManagerDto);

    } catch (Exception e) {

      logger.error("请求展示列表异常:" + e.getMessage(), e);
      return ServerResponse.createByErrorMessage("请求展示列表异常");
    }

  }


  /**
   * 新增excel模板
   * 
   * @param file
   * @param sourceDataManagerDto
   * @return
   */
  @PostMapping(value = "/sourceDataMgr/addExcel")
  @OptLog(logType = LogTypeEnum.OPERATION, module = "autoPackage", description = "添加源数据")
  public ServerResponse addExcel(MultipartFile file, SourceDataManagerDTO sourceDataManagerDto,
      HttpSession session) {

    int flag = 0;
    ExcelVo newExc = new ExcelVo();
    try {
      // 获取用户项目信息
      SysUsr user = (SysUsr) session.getAttribute("user");

      Project project = Utils.getProject(sourceDataManagerDto.getProjectId(), user);

      String basePath = UPLOAD + File.separator;
      String personalPath = basePath + user.getUsrId() + File.separator;
      String uploadDir = System.getProperty(userHome) + File.separator + personalPath;
      // 创建账套文件路径
      File dir = new File(uploadDir);
      if (!dir.exists()) {
        dir.mkdirs();
      }
      String originalName = file.getOriginalFilename();

      // 这个就是把时间戳经过处理得到期望格式的时间
      Date ss = new Date();
      SimpleDateFormat format0 = new SimpleDateFormat(DATEFORMAT);
      String time = format0.format(ss.getTime());
      String fileName = time + "." + originalName.substring(originalName.lastIndexOf('.') + 1);
      File serverFile = new File(uploadDir + fileName);
      file.transferTo(serverFile);
      File excelFile = new File(serverFile.getAbsolutePath());
      // 获取excel后缀名
      String excelLastName =
          excelFile.getName().substring(excelFile.getName().lastIndexOf('.') + 1);
      // excel解析
      if ("xlsx".equalsIgnoreCase(excelLastName)) {
        Map<String, Object> map = excelService.excelAnalyseXlsx(user,
            sourceDataManagerDto.getProjectId(), excelFile, excelFile.getName(), flag);
        if (!(boolean) map.get(SUCCESS)) {
          FileUtils.deleteQuietly(excelFile);
          return ServerResponse.createByErrorMessage("上传文件解析失败");
        }
      }

      newExc.setClientId(sourceDataManagerDto.getProjectId());
      newExc.setDataNm(sourceDataManagerDto.getFileName());
      newExc.setFileUrl(excelFile.getPath());
      if (StringUtils.isEmpty(sourceDataManagerDto.getRemark())) {
        newExc.setRemark("");
      } else {
        newExc.setRemark(sourceDataManagerDto.getRemark().trim());
      }
      newExc.setClientNm(sourceDataManagerDto.getProjectName());
      newExc.setDelInd("0");
      excelService.insertClientManage(user, newExc, excelFile.getPath(), project);

    } catch (Exception e) {
      File dir = new File(newExc.getFileUrl());
      FileUtils.deleteQuietly(dir);
      return ServerResponse.createByErrorMessage(e.getMessage());
    }
    return ServerResponse.createBySuccess();
  }





}
